/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.

This file is part of Quake III Arena source code.

Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
 */
//

/*****************************************************************************
 * name:		ai_main.h
 *
 * desc:		Quake3 bot AI
 *
 * $Archive: /source/code/botai/ai_chat.c $
 *
 *****************************************************************************/

//#define DEBUG
#define CTF

#define MAX_ITEMS					256
//bot flags
#define BFL_STRAFERIGHT				1	//strafe to the right
#define BFL_ATTACKED				2	//bot has attacked last ai frame
#define BFL_ATTACKJUMPED			4	//bot jumped during attack last frame
#define BFL_AIMATENEMY				8	//bot aimed at the enemy this frame
#define BFL_AVOIDRIGHT				16	//avoid obstacles by going to the right
#define BFL_IDEALVIEWSET			32	//bot has ideal view angles set
#define BFL_FIGHTSUICIDAL			64	//bot is in a suicidal fight
//long term goal types
#define LTG_TEAMHELP				1	//help a team mate
#define LTG_TEAMACCOMPANY			2	//accompany a team mate
#define LTG_DEFENDKEYAREA			3	//defend a key area
#define LTG_GETFLAG					4	//get the enemy flag
#define LTG_RUSHBASE				5	//rush to the base
#define LTG_RETURNFLAG				6	//return the flag
#define LTG_CAMP					7	//camp somewhere
#define LTG_CAMPORDER				8	//ordered to camp somewhere
#define LTG_PATROL					9	//patrol
#define LTG_GETITEM					10	//get an item
#define LTG_KILL					11	//kill someone
#define LTG_HARVEST					12	//harvest skulls
#define LTG_ATTACKENEMYBASE			13	//attack the enemy base
#define LTG_MAKELOVE_UNDER			14
#define LTG_MAKELOVE_ONTOP			15
//some goal dedication times
#define TEAM_HELP_TIME				60	//1 minute teamplay help time
#define TEAM_ACCOMPANY_TIME			600	//10 minutes teamplay accompany time
#define TEAM_DEFENDKEYAREA_TIME		600	//10 minutes ctf defend base time
#define TEAM_CAMP_TIME				600	//10 minutes camping time
#define TEAM_PATROL_TIME			600	//10 minutes patrolling time
#define TEAM_LEAD_TIME				600	//10 minutes taking the lead
#define TEAM_GETITEM_TIME			60	//1 minute
#define	TEAM_KILL_SOMEONE			180	//3 minute to kill someone
#define TEAM_ATTACKENEMYBASE_TIME	600	//10 minutes
#define TEAM_HARVEST_TIME			120	//2 minutes
#define CTF_GETFLAG_TIME			600	//10 minutes ctf get flag time
#define CTF_RUSHBASE_TIME			120	//2 minutes ctf rush base time
#define CTF_RETURNFLAG_TIME			180	//3 minutes to return the flag
#define CTF_ROAM_TIME				60	//1 minute ctf roam time
//patrol flags
#define PATROL_LOOP					1
#define PATROL_REVERSE				2
#define PATROL_BACK					4
//teamplay task preference
#define TEAMTP_DEFENDER				1
#define TEAMTP_ATTACKER				2
//CTF strategy
#define CTFS_AGRESSIVE				1
//copied from the aas file header
#define PRESENCE_NONE				1
#define PRESENCE_NORMAL				2
#define PRESENCE_CROUCH				4
//
#define MAX_PROXMINES				64

//check points

typedef struct bot_waypoint_s {
    int inuse;
    char name[32];
    bot_goal_t goal;
    struct bot_waypoint_s *next, *prev;
} bot_waypoint_t;

#define MAX_ACTIVATESTACK		8
#define MAX_ACTIVATEAREAS		32

typedef struct bot_activategoal_s {
    int inuse;
    bot_goal_t goal; //goal to activate (buttons etc.)
    float time; //time to activate something
    float start_time; //time starting to activate something
    float justused_time; //time the goal was used
    int shoot; //true if bot has to shoot to activate
    int weapon; //weapon to be used for activation
    vec3_t target; //target to shoot at to activate something
    vec3_t origin; //origin of the blocking entity to activate
    int areas[MAX_ACTIVATEAREAS]; //routing areas disabled by blocking entity
    int numareas; //number of disabled routing areas
    int areasdisabled; //true if the areas are disabled for the routing
    struct bot_activategoal_s *next; //next activate goal on stack
} bot_activategoal_t;

//bot state

typedef struct bot_state_s {
    int inuse; //true if this state is used by a bot client
    int botthink_residual; //residual for the bot thinks
    int client; //client number of the bot
    int entitynum; //entity number of the bot
    playerState_t cur_ps; //current player state
    int last_eFlags; //last ps flags
    usercmd_t lastucmd; //usercmd from last frame
    int entityeventTime[1024]; //last entity event time
    //
    bot_settings_t settings; //several bot settings
    int (*ainode)(struct bot_state_s * bs); //current AI node
    float thinktime; //time the bot thinks this frame
    vec3_t origin; //origin of the bot
    vec3_t velocity; //velocity of the bot
    int presencetype; //presence type of the bot
    vec3_t eye; //eye coordinates of the bot
    int areanum; //the number of the area the bot is in
    int inventory[MAX_ITEMS]; //string with items amounts the bot has
    int tfl; //the travel flags the bot uses
    int flags; //several flags
    int respawn_wait; //wait until respawned
    int lasthealth; //health value previous frame
    int lastkilledplayer; //last killed player
    int lastkilledby; //player that last killed this bot
    int botdeathtype; //the death type of the bot
    int enemydeathtype; //the death type of the enemy
    int botsuicide; //true when the bot suicides
    int enemysuicide; //true when the enemy of the bot suicides
    int setupcount; //true when the bot has just been setup
    int map_restart; //true when the map is being restarted
    int entergamechat; //true when the bot used an enter game chat
    int num_deaths; //number of time this bot died
    int num_kills; //number of kills of this bot
    int revenge_enemy; //the revenge enemy
    int revenge_kills; //number of kills the enemy made
    int lastframe_health; //health value the last frame
    int lasthitcount; //number of hits last frame
    int chatto; //chat to all or team
    float walker; //walker charactertic
    float ltime; //local bot time
    float entergame_time; //time the bot entered the game
    float ltg_time; //long term goal time
    float nbg_time; //nearby goal time
    float respawn_time; //time the bot takes to respawn
    float respawnchat_time; //time the bot started a chat during respawn
    float chase_time; //time the bot will chase the enemy
    float enemyvisible_time; //time the enemy was last visible
    float check_time; //time to check for nearby items
    float stand_time; //time the bot is standing still
    float lastchat_time; //time the bot last selected a chat
    float kamikaze_time; //time to check for kamikaze usage
    float invulnerability_time; //time to check for invulnerability usage
    float standfindenemy_time; //time to find enemy while standing
    float attackstrafe_time; //time the bot is strafing in one dir
    float attackcrouch_time; //time the bot will stop crouching
    float attackchase_time; //time the bot chases during actual attack
    float attackjump_time; //time the bot jumped during attack
    float enemysight_time; //time before reacting to enemy
    float enemydeath_time; //time the enemy died
    float enemyposition_time; //time the position and velocity of the enemy were stored
    float defendaway_time; //time away while defending
    float defendaway_range; //max travel time away from defend area
    float rushbaseaway_time; //time away from rushing to the base
    float attackaway_time; //time away from attacking the enemy base
    float harvestaway_time; //time away from harvesting
    float ctfroam_time; //time the bot is roaming in ctf
    float killedenemy_time; //time the bot killed the enemy
    float arrive_time; //time arrived (at companion)
    float lastair_time; //last time the bot had air
    float teleport_time; //last time the bot teleported
    float camp_time; //last time camped
    float camp_range; //camp range
    float weaponchange_time; //time the bot started changing weapons
    float firethrottlewait_time; //amount of time to wait
    float firethrottleshoot_time; //amount of time to shoot
    float notblocked_time; //last time the bot was not blocked
    float blockedbyavoidspot_time; //time blocked by an avoid spot
    float predictobstacles_time; //last time the bot predicted obstacles
    int predictobstacles_goalareanum; //last goal areanum the bot predicted obstacles for
    vec3_t aimtarget;
    vec3_t enemyvelocity; //enemy velocity 0.5 secs ago during battle
    vec3_t enemyorigin; //enemy origin 0.5 secs ago during battle
    //
    int kamikazebody; //kamikaze body
    int proxmines[MAX_PROXMINES];
    int numproxmines;
    //
    int character; //the bot character
    int ms; //move state of the bot
    int gs; //goal state of the bot
    int cs; //chat state of the bot
    int ws; //weapon state of the bot
    //
    int enemy; //enemy entity number
    int lastenemyareanum; //last reachability area the enemy was in
    vec3_t lastenemyorigin; //last origin of the enemy in the reachability area
    int weaponnum; //current weapon number
    vec3_t viewangles; //current view angles
    vec3_t ideal_viewangles; //ideal view angles
    vec3_t viewanglespeed;
    //
    int ltgtype; //long term goal type
    // team goals
    int teammate; //team mate involved in this team goal
    int decisionmaker; //player who decided to go for this goal
    int ordered; //true if ordered to do something
    float order_time; //time ordered to do something
    int owndecision_time; //time the bot made it's own decision
    bot_goal_t teamgoal; //the team goal
    bot_goal_t altroutegoal; //alternative route goal
    float reachedaltroutegoal_time; //time the bot reached the alt route goal
    float teammessage_time; //time to message team mates what the bot is doing
    float teamgoal_time; //time to stop helping team mate
    float teammatevisible_time; //last time the team mate was NOT visible
    int teamtaskpreference; //team task preference
    // last ordered team goal
    int lastgoal_decisionmaker;
    int lastgoal_ltgtype;
    int lastgoal_teammate;
    bot_goal_t lastgoal_teamgoal;
    // for leading team mates
    int lead_teammate; //team mate the bot is leading
    bot_goal_t lead_teamgoal; //team goal while leading
    float lead_time; //time leading someone
    float leadvisible_time; //last time the team mate was visible
    float leadmessage_time; //last time a messaged was sent to the team mate
    float leadbackup_time; //time backing up towards team mate
    //
    char teamleader[32]; //netname of the team leader
    float askteamleader_time; //time asked for team leader
    float becometeamleader_time; //time the bot will become the team leader
    float teamgiveorders_time; //time to give team orders
    float lastflagcapture_time; //last time a flag was captured
    int numteammates; //number of team mates
    int redflagstatus; //0 = at base, 1 = not at base
    int blueflagstatus; //0 = at base, 1 = not at base
    int neutralflagstatus; //0 = at base, 1 = our team has flag, 2 = enemy team has flag, 3 = enemy team dropped the flag
    int flagstatuschanged; //flag status changed
    int forceorders; //true if forced to give orders
    int flagcarrier; //team mate carrying the enemy flag
    int ctfstrategy; //ctf strategy
    char subteam[32]; //sub team name
    float formation_dist; //formation team mate intervening space
    char formation_teammate[16]; //netname of the team mate the bot uses for relative positioning
    float formation_angle; //angle relative to the formation team mate
    vec3_t formation_dir; //the direction the formation is moving in
    vec3_t formation_origin; //origin the bot uses for relative positioning
    bot_goal_t formation_goal; //formation goal

    bot_activategoal_t *activatestack; //first activate goal on the stack
    bot_activategoal_t activategoalheap[MAX_ACTIVATESTACK]; //activate goal heap

    bot_waypoint_t *checkpoints; //check points
    bot_waypoint_t *patrolpoints; //patrol points
    bot_waypoint_t *curpatrolpoint; //current patrol point the bot is going for
    int patrolflags; //patrol flags
} bot_state_t;

//resets the whole bot state
void BotResetState(bot_state_t *bs);
//returns the number of bots in the game
int NumBots(void);
//returns info about the entity
void BotEntityInfo(int entnum, aas_entityinfo_t *info);

extern float floattime;
#define FloatTime() floattime

// from the game source
void QDECL BotAI_Print(int type, char *fmt, ...);
void QDECL QDECL BotAI_BotInitialChat(bot_state_t *bs, char *type, ...);
void BotAI_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
int BotAI_GetClientState(int clientNum, playerState_t *state);
int BotAI_GetEntityState(int entityNum, entityState_t *state);
int BotAI_GetSnapshotEntity(int clientNum, int sequence, entityState_t *state);
int BotTeamLeader(bot_state_t *bs);
